home *** CD-ROM | disk | FTP | other *** search
- // =============================================================================
- // COMPILER-INDEPENDENT GLOBAL STORAGE
- // ©1994-96 Alessandro Levi Montalcini <alm@torino.alpcom.it>
- // The latest version is available on ftp://ftp.alpcom.it/software/mac/LMontalcini
- // This text looks best in monaco 9 font, 4 spaces per tab, no wrapping
-
- // WARNING: THIS HEADER SHOULD ONLY BE INCLUDED ONCE THROUGHOUT THE PROJECT
-
- // Unaltered copies of this file may be freely distributed; you may use this
- // code in your projects without asking my permission and modify it for your
- // personal use, but you should not distribute any modified versions. Send
- // me your additions if you want them to be included in the next version.
-
- // If you use this header in your projects, I'd be happy to get some credits
- // or to receive a copy of the program. However, this is absolutely not
- // required if you can't do it for any reason.
-
- //==============================================================================
- // Original code and comments are copyright ©Alessandro Levi Montalcini (ALM)
- // ALM 11/23/94: released as part of the KeyQuencer developer's toolkit
- // ALM 04/01/95: changed defined(powerc) to GENERATINGPOWERPC
- // ALM 05/18/95: merged ALM and RMT macros, added comments and sample code
-
- // Additions to A4Globals.h by Robert M. Thorne of Aladdin Systems, Inc. (RMT)
- // RMT Add code to make this conditional if A4 based.
- // RMT 4/20/95: fixed macro for MWerks (was redefining GLOBALS_ALWAYS_AVAILABLE)
- //==============================================================================
-
- #ifndef _H_a4globals
- #define _H_a4globals
-
- //==============================================================================
- // Check if the current project needs to set up the environment before accessing
- // its global variables. Globals are always available in PowerPC code fragments
- // and in 68K applications, whereas 68K A4-based projects have to set up the A4
- // register before using the globals and restore it when they are done.
- // Note: this method can't be used to gain access to 68K A5-based application
- // globals from callback routines such as VBL or Time Manager tasks.
- // (this section was originally conceived by RMT)
-
- #if GENERATINGPOWERPC // any PowerPC compiler
-
- #define GLOBALS_ALWAYS_AVAILABLE 1
-
- #elif defined(THINK_C) // Think C 68K
-
- #if __option(a4_globals)
- #define GLOBALS_ALWAYS_AVAILABLE 0
- #else
- #define GLOBALS_ALWAYS_AVAILABLE 1
- #endif
-
- #elif defined(__MWERKS__) // CodeWarrior 68K
-
- #if __A5__
- #define GLOBALS_ALWAYS_AVAILABLE 1
- #else
- #define GLOBALS_ALWAYS_AVAILABLE 0
- #endif
-
- #else // unknown compiler, stop here
-
- #error unsupported compiler
-
- #endif // end of project type check
-
- //==============================================================================
- // The following macros can be used by any project to set up and restore the
- // globals environment. Both the Think C and CodeWarrior headers include static
- // code, so this header should only be included once throughout the project.
- //
- // The #include "A4Globals.h" statement should be at the beginning of the source
- // file containing the main routine; you should declare a "world" local variable
- // of type "long" and call MAIN_SETUP_GLOBALS(world) at the beginning of the
- // main routine and MAIN_RESTORE_GLOBALS(world) at the end. Remember not to use
- // any "return" statement between the two macros, or you'll return to the caller
- // without restoring the A4 register (which can be really bad). Also, don't try
- // to use global variables after the MAIN_RESTORE_GLOBALS macro; if you need a
- // global for your function result, copy it to a local variable. You can use the
- // TEMP_SETUP_GLOBALS and TEMP_RESTORE_GLOBALS macros in routines that are
- // called without going through the main entry point, as long as they are in
- // the same file as the main routine. See below for more information on how to
- // access global variables from code that lives in other source files and gets
- // called without going through main.
-
- #if GLOBALS_ALWAYS_AVAILABLE // PowerPC code fragment or 68K application
-
- #define MAIN_SETUP_GLOBALS(x) { x = 0; } // to avoid "unused var" warnings
- #define MAIN_RESTORE_GLOBALS(x)
- #define TEMP_SETUP_GLOBALS(x) { x = 0; }
- #define TEMP_RESTORE_GLOBALS(x)
-
- #elif defined(THINK_C) // Think C A4-based project
-
- #include <SetUpA4.h>
- #define MAIN_SETUP_GLOBALS(x) { RememberA0(); SetUpA4(); asm { MOVE.L (A7)+, x } }
- #define MAIN_RESTORE_GLOBALS(x) { asm { MOVE.L x, -(A7) } RestoreA4(); }
- #define TEMP_SETUP_GLOBALS(x) { SetUpA4(); asm { MOVE.L (A7)+, x } }
- #define TEMP_RESTORE_GLOBALS(x) { asm { MOVE.L x, -(A7) } RestoreA4(); }
-
- #elif defined(__MWERKS__) // CodeWarrior A4-based project
-
- #include <A4Stuff.h>
- #include <SetUpA4.h>
- #define MAIN_SETUP_GLOBALS(x) { x = SetCurrentA4(); RememberA4(); }
- #define MAIN_RESTORE_GLOBALS(x) { (void)SetA4(x); }
- #define TEMP_SETUP_GLOBALS(x) { x = SetUpA4(); }
- #define TEMP_RESTORE_GLOBALS(x) { (void)RestoreA4(x); }
-
- #endif // end of compiler-specific macros
-
- //==============================================================================
- // After you set up the environment, all the project globals are available to
- // your code no matter what source file it lives in. In some cases, however,
- // your code is called without going through the main entry point (callback
- // routines, periodic tasks, trap patches and so forth). If this code is in
- // the same file as the main routine, you can use TEMP_SETUP_GLOBALS and
- // TEMP_RESTORE_GLOBALS; otherwise, you should add a couple of routines to
- // your main source file whose only task in life is to set up and restore the
- // environment for you. Here's a simple example with two source files that
- // shows how to use the macros correctly:
- /*
- ------------------------ FILE: main.c ------------------------
-
- #include "A4Globals.h"
- #include "other.h"
-
- // Global variables:
- long gNumTimesCalled;
-
- // Main entry point; set up globals, call routines and install callbacks:
- pascal OSErr main(void)
- {
- long world;
-
- MAIN_SETUP_GLOBALS(world);
- DoSomethingFromMainFile();
- DoSomethingFromOtherFile();
- InstallCallbackRoutine(CallbackFromMainFile);
- InstallCallbackRoutine(CallbackFromOtherFile);
- MAIN_RESTORE_GLOBALS(world);
- return noErr;
- }
-
- // Called when the globals are already available, no need to set them up again:
- void DoSomethingFromMainFile(void)
- {
- gNumTimesCalled = 0L;
- }
-
- // Called without going through main, set up globals with TEMP_SETUP_GLOBALS:
- pascal long CallbackFromMainFile(void)
- {
- long world, timesCalled;
-
- TEMP_SETUP_GLOBALS(world);
- ++gNumTimesCalled;
- timesCalled = gNumTimesCalled;
- TEMP_RESTORE_GLOBALS(world);
- return timesCalled;
- }
-
- // Set up the globals environment for routines that live in other files:
- long SetupGlobalsWorld(void)
- {
- long world;
-
- TEMP_SETUP_GLOBALS(world);
- return world;
- }
-
- // Restore the globals environment for routines that live in other files:
- void RestoreGlobalsWorld(long world)
- {
- TEMP_RESTORE_GLOBALS(world);
- }
-
- ------------------------ FILE: other.c ------------------------
-
- #include "main.h"
-
- // Global variables:
- extern long gNumTimesCalled;
-
- // Although not in the main file, this is called when the globals are already available:
- void DoSomethingFromOtherFile(void)
- {
- gNumTimesCalled = 0L;
- }
-
- // Called without going through main, can't use the macros; call SetupGlobalsWorld instead:
- pascal long CallbackFromOtherFile(void)
- {
- long world, timesCalled;
-
- world = SetupGlobalsWorld();
- ++gNumTimesCalled;
- timesCalled = gNumTimesCalled;
- RestoreGlobalsWorld(world);
- return timesCalled;
- }
- */
- //==============================================================================
-
- #endif // _H_a4globals
-
- //==============================================================================
-
-